package com.googlecode.neuron.jmx;

import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.OperatingSystemMXBean;
import java.lang.management.RuntimeMXBean;
import java.util.Set;

import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;

public class JmxDemo {

	public static void main(String[] args) {
		try {
			// Create an RMI connector client and
			// connect it to the RMI connector server
			//
			echo("\nCreate an RMI connector client and " + "connect it to the RMI connector server");
			JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:9999/jmxrmi");
			JMXConnector jmxConnector = JMXConnectorFactory.connect(url, null);

			// Get an MBeanServerConnection
			//
			echo("\nGet an MBeanServerConnection");
			MBeanServerConnection connection = jmxConnector.getMBeanServerConnection();
			waitForEnterPressed();

			// Get domains from MBeanServer
			//
			echo("\nDomains:");
			String domains[] = connection.getDomains();
			for (int i = 0; i < domains.length; i++) {
				echo("\tDomain[" + i + "] = " + domains[i]);
			}
			waitForEnterPressed();

			// Get MBeanServer's default domain
			//
			String domain = connection.getDefaultDomain();
			echo("\nDomain = " + domain);
			// Get MBean count
			//
			echo("\nMBean count = " + connection.getMBeanCount());

			// Query MBean names
			//
			echo("\nQuery MBeanServer MBeans:");
			Set<ObjectName> names = connection.queryNames(null, null);
			for (ObjectName name : names) {
				echo("\tObjectName = " + name);
			}
			waitForEnterPressed();

			// RuntimeMXBean
			RuntimeMXBean runtime = ManagementFactory.newPlatformMXBeanProxy(connection, ManagementFactory.RUNTIME_MXBEAN_NAME, RuntimeMXBean.class);
			echo("\tBootClassPath           = " + runtime.getBootClassPath());
			echo("\tClassPath               = " + runtime.getClassPath());
			echo("\tLibraryPath             = " + runtime.getLibraryPath());
			echo("\tManagementSpecVersion   = " + runtime.getManagementSpecVersion());
			echo("\tName                    = " + runtime.getName());
			echo("\tSpecName                = " + runtime.getSpecName());
			echo("\tSpecVendor              = " + runtime.getSpecVendor());
			echo("\tSpecVersion             = " + runtime.getSpecVersion());
			echo("\tStartTime               = " + runtime.getStartTime());
			echo("\tUptime                  = " + runtime.getUptime());
			echo("\tVmName                  = " + runtime.getVmName());
			echo("\tVmVendor                = " + runtime.getVmVendor());
			echo("\tVmVersion               = " + runtime.getVmVersion());
			echo("\tInputArguments          = " + runtime.getInputArguments());
			echo("\tSystemProperties        = " + runtime.getSystemProperties());

			waitForEnterPressed();

			// OperatingSystemMXBean
			OperatingSystemMXBean os = ManagementFactory.newPlatformMXBeanProxy(connection, ManagementFactory.OPERATING_SYSTEM_MXBEAN_NAME, OperatingSystemMXBean.class);
			echo("\tArch                = " + os.getArch());
			echo("\tAvailableProcessors = " + os.getAvailableProcessors());
			echo("\tName                = " + os.getName());
			echo("\tSystemLoadAverage   = " + os.getSystemLoadAverage());
			echo("\tVersion             = " + os.getVersion());

			for (int i = 0; i < 3; i++) {
				waitForEnterPressed();
				MemoryMXBean mem = ManagementFactory.newPlatformMXBeanProxy(connection, ManagementFactory.MEMORY_MXBEAN_NAME, MemoryMXBean.class);
				echo("\tObjectPendingFinalizationCount = " + mem.getObjectPendingFinalizationCount());
				echo("\tHeapMemoryUsage                = " + mem.getHeapMemoryUsage());
				echo("\tNonHeapMemoryUsage             = " + mem.getNonHeapMemoryUsage());
			}

			jmxConnector.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private static void echo(String msg) {
		System.out.println(msg);
	}

	protected static void sleep(int millis) {
		try {
			Thread.sleep(millis);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	private static void waitForEnterPressed() {
		try {
			echo("\nPress <Enter> to continue...");
			System.in.read();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
